package com.rsscollector.model;

import java.util.List;
import java.util.Collections;
import java.util.Comparator;
import java.util.ArrayList;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import com.rsscollector.model.vo.Category;
import com.rsscollector.model.vo.RssProvider;
import com.rsscollector.model.vo.RssSource;
import com.rsscollector.model.vo.RssContent;
import com.rsscollector.util.PersistenceUtil;
import com.rsscollector.util.StringUtil;

public class CatalogFacade {

    public static List getRootCategories(boolean inactiveItemsIncluded) {
        EntityManager em = PersistenceUtil.getEntityManager();
        String queryStr = "SELECT c FROM Category c WHERE c.parentCategory IS NULL ";
        if (!inactiveItemsIncluded) {
            queryStr += " AND c.active = TRUE";
        }
        queryStr += " ORDER BY c.sequence";
        Query q = em.createQuery(queryStr);
        List categories = q.getResultList();
        return categories;
    }

    public static Category getCategory(String categoryId) {
        EntityManager em = PersistenceUtil.getEntityManager();
        Long catId = new Long(categoryId);
        return em.find(Category.class, catId);
    }

    public static List getItemsForCategory(String catId) {
        List items = null;
        if (catId != null && !catId.equals("")) {
            Long categoryId = new Long(catId);
            EntityManager em = PersistenceUtil.getEntityManager();
            String queryStr = "SELECT DISTINCT c FROM RssContent AS c JOIN c.rssSource AS s JOIN s.categories cat " +
                    "WHERE cat.id = ?1 AND c.active = TRUE ORDER BY c.publishedDate DESC";
            Query q = em.createQuery(queryStr).setParameter(1, categoryId);
            q.setFirstResult(1);
            q.setMaxResults(30);
            items = q.getResultList();
        }
        return items;
    }

    public static List getItemsForHomePage(String categoryId) {
        EntityManager em = PersistenceUtil.getEntityManager();
        List items = null;
        String queryStr = "SELECT DISTINCT c FROM RssContent AS c JOIN c.rssSource AS s JOIN s.categories cat " +
                "WHERE cat.id = ?1 AND c.active = TRUE ORDER BY c.publishedDate DESC";
        Long catId = new Long (categoryId);
        Query q = em.createQuery(queryStr).setParameter(1, catId);
        q.setFirstResult(1);
        q.setMaxResults(3);
        items = q.getResultList();
        // move the item that have image link to the first
        List temp = new ArrayList();
        // get the first news that have image link
        boolean haveNotImageLink = true;
        if (items != null) {
            for (int i = 0; i < items.size(); i++) {
                RssContent obj = (RssContent) temp.get(i);
                if (!StringUtil.isEmpty(obj.getImageLink()) && haveNotImageLink) {
                    temp.add(0, obj); // add to the first
                    haveNotImageLink = false;
                } else {
                    temp.add(obj);
                }
            }
        }
        System.out.println("size="+temp.size());
        items = temp;
        return items;
    }

    public static Category createCategory(String name, String title, Long parentCategoryId) {
        EntityManager em = PersistenceUtil.getEntityManagerWithTX();

        /* get max sequence number */
        long nextSequence;
        Category parentCat = em.find(Category.class, parentCategoryId);
        Query q;
        if (parentCat != null) {
            q = em.createQuery("select max(cat.sequence) from Category as cat where cat.parentCategory = ?1");
            q.setParameter(1, parentCat);
        } else {
            q = em.createQuery("select max(cat.sequence) from Category as cat where cat.parentCategory is NULL");
        }
        Long maxSequence = (Long) q.getSingleResult();
        if (maxSequence != null) {
            nextSequence = maxSequence.longValue() + 1;
        } else {
            nextSequence = 1;
        }

        /* create category */
        Category cat = new Category(name, true, nextSequence, parentCat);
        cat.setTitle(title);

        if (parentCat != null) {
            if (!parentCat.getSubCategories().contains(cat)) {
                parentCat.getSubCategories().add(cat);
            }
            em.persist(parentCat);
        }

        em.persist(cat);

        PersistenceUtil.endTransaction();
        return cat;
    }

    /**
     * Removes a category and its subcategories.
     *
     * @param id ID of the category to be removed
     */
    public static void removeCategory(Long id) {
        EntityManager em = PersistenceUtil.getEntityManagerWithTX();
        Category cat = em.find(Category.class, id);
        if (cat != null) {
            /* subcategories will be removed automatically because cascade=ALL */
            em.remove(cat);
        }
        PersistenceUtil.endTransaction();
    }

    public static void createRssUrl(String newUrl, Long catId, String urlProvider) {
        EntityManager em = PersistenceUtil.getEntityManagerWithTX();
        Category cat = em.find(Category.class, catId);
        RssSource source = RssSourceFacade.createRssSource(newUrl, urlProvider);

        if (!source.getCategories().contains(cat)) source.getCategories().add(cat);
        if (!cat.getRssSources().contains(source)) cat.getRssSources().add(source);

        em.persist(cat);
        em.persist(source);

        PersistenceUtil.endTransaction();
    }

    public static void removeRssUrl(Long id, Long catId) {
        EntityManager em = PersistenceUtil.getEntityManagerWithTX();
        RssSource source = em.find(RssSource.class, id);
        if (source != null) {
            if (source.getCategories().size() <= 1) {
                RssProvider provider = source.getRssProvider();
                if (provider != null) {
                    provider.getRssSources().remove(source);
                    em.persist(provider);
                }

                for (Category cat : source.getCategories()) {
                    cat.getRssSources().remove(source);
                    em.persist(cat);
                }

                em.remove(source);
            } else {
                Category cat = em.find(Category.class, catId);
                if (cat != null) {
                    cat.getRssSources().remove(source);
                    em.persist(cat);
                    source.getCategories().remove(cat);
                    em.persist(source);
                }
            }
        }
        PersistenceUtil.endTransaction();
    }
}
